package com.norns.torque.view

import android.Manifest
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothHeadset
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Observer
import com.drake.brv.utils.divider
import com.drake.brv.utils.linear
import com.drake.brv.utils.models
import com.drake.brv.utils.setup
import com.gyf.immersionbar.ImmersionBar
import com.hi.dhl.binding.viewbind
import com.permissionx.guolindev.PermissionX
import com.norns.torque.DeviceScanViewModel
import com.norns.torque.R
import com.norns.torque.bluetooth.ChatServer
import com.norns.torque.databinding.ActivityScanBinding
import com.norns.torque.databinding.ItemBluetoothDeviceBinding
import com.norns.torque.databinding.ItemFootBinding
import com.norns.torque.dialog.AppCommonDialog
import com.norns.torque.dialog.LoadingDialog
import com.norns.torque.entrty.DeviceScanViewState
import com.norns.torque.entrty.WifiDevice
import com.norns.torque.utils.AppConstant
import timber.log.Timber


class ScanActivity : AppCompatActivity() {
    private val binding: ActivityScanBinding by viewbind()
    private val viewModel: DeviceScanViewModel by viewModels()
    private var loadingDialog: LoadingDialog? = null

    companion object {
        const val countdown: Int = 124
    }

    private val handler: Handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            if (countdown == msg.what) {
                val connectionState = ChatServer.connectedState
                if (connectionState != AppConstant.connectionSuccess) {//连接成功
                    hidLoadingDialog()
                    Toast.makeText(this@ScanActivity, "连接失败", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(newBase)
        overrideFontScale(newBase)
    }

    /**
     * 重置配置 fontScale：保持字体比例不变，始终为 1.
     */
    private fun overrideFontScale(context: Context?) {
        if (context == null) return
        context.resources.configuration.let {
            it.fontScale = 1f // 保持字体比例不变，始终为 1.
            applyOverrideConfiguration(it) // 应用新的配置
        }
    }



    private val viewStateObserver = Observer<DeviceScanViewState> { state ->
        when (state) {
            is DeviceScanViewState.ScanResults -> showResults(state.scanDeviceList)
            is DeviceScanViewState.ScanCompletion -> { stopProgressView() }
            is DeviceScanViewState.Error -> showError(state.message)
        }
    }

    private val activityLauncher = this.registerForActivityResult<Intent, ActivityResult>(
        ActivityResultContracts.StartActivityForResult()
    ) { result: ActivityResult? ->
        //Timber.d("打开蓝牙：${result?.resultCode}")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ImmersionBar.with(this).statusBarColor(R.color.main)
            .navigationBarColor(R.color.white)
            .autoStatusBarDarkModeEnable(true,0.2f)
            .init()

        searchBluetoothDevice()
        initView()
        subscribeToModel()
    }

    private fun subscribeToModel() {
        viewModel.viewState.observe(this, viewStateObserver)
        viewModel.bluetoothState.observe(this){value->
            if (value == BluetoothAdapter.STATE_ON) { // 蓝牙已开启
                viewModel.stopScanning()
                searchBluetoothDevice()
            }else if (value == BluetoothAdapter.STATE_OFF){
                viewModel.stopScanning()
            }
        }
        viewModel.connectionState.observe(this){value->
            if (value == AppConstant.connectionSuccess) {//连接成功
                hidLoadingDialog()
                val intent = Intent(this@ScanActivity, PeakValueActivity::class.java)
                startActivity(intent)
                finish()
            } else if (value == AppConstant.connectionField) {//连接失败
                hidLoadingDialog()
                Toast.makeText(this, "连接失败", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun initView() {
        ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
        binding.btnBack.setOnClickListener { finish() }
        binding.btnMore.setOnClickListener { finish() }
        binding.tvScanDevice.setOnClickListener {
            binding.tvScanDevice.isEnabled = false
            showLoading()
            searchBluetoothDevice()
        }
        binding.bluetoothList.divider {
            setDivider(5, true)
            endVisible = true
        }.linear()
            .setup {
                addType<WifiDevice> {
                    if (type == "foot") {
                        R.layout.item_foot
                    } else {
                        R.layout.item_bluetooth_device
                    }
                }
                onBind {
                    when (itemViewType) {
                        R.layout.item_bluetooth_device -> {
                            val binding =
                                getBinding<ItemBluetoothDeviceBinding>() // ViewBinding/DataBinding都支持
                            val data = getModel<WifiDevice>()
                            binding.tvDeviceName.text = data.name
                            binding.tvDeviceMac.text = data.address
                            binding.tvContentState.text = data.contentState
                            binding.tvDistance.text = data.distance
                        }

                        R.layout.item_foot -> {
                            val binding =
                                getBinding<ItemFootBinding>() // ViewBinding/DataBinding都支持
                            val data = getModel<WifiDevice>()
                            binding.tvFoot.text = data.name
                        }
                    }
                }
                onClick(R.id.tvContent) {
                    val data = getModel<WifiDevice>()
                    viewModel.stopScanning()
                    connectionBluetooth(data.address)
                }
            }
    }

    private fun connectionBluetooth(mac: String) {
        val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        val bluetoothAdapter = bluetoothManager.adapter
        if (null == bluetoothAdapter || !bluetoothAdapter.isEnabled) {
            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            activityLauncher.launch(enableBtIntent)
            return
        }
        val device = viewModel.getBluetoothDevice(mac)
        device?.let {
            loadingDialog = LoadingDialog.newInstance("连接中...")
            loadingDialog!!.show(supportFragmentManager, "LoadingDialog")
            handler.sendEmptyMessageDelayed(countdown, 10000)
            viewModel.setCurrentChatConnection(device)
        }
    }

    private fun requestBluetoothPermission() {
        PermissionX.init(this)
            .permissions(
                arrayListOf<String>(
                    Manifest.permission.BLUETOOTH_SCAN,
                    Manifest.permission.BLUETOOTH_ADVERTISE,
                    Manifest.permission.BLUETOOTH_CONNECT
                )
            )
            .onExplainRequestReason { scope, deniedList ->
                val message = "需要您同意以下权限才能正常使用"
                scope.showRequestReasonDialog(deniedList, message, "Allow", "Deny")
            }
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    Timber.d("申请蓝牙权限通过")
                    checkLocationPermissions()
                    //Toast.makeText(this, "所有申请的权限都已通过", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "您拒绝了如下权限：$deniedList", Toast.LENGTH_SHORT).show()
                }
            }

    }

    private fun requestBluetoothLocationPermission(list: ArrayList<String>) {
        PermissionX.init(this)
            .permissions(
                list
            )
            .onExplainRequestReason { scope, deniedList ->
                val message = "需要您同意以下权限才能正常使用"
                scope.showRequestReasonDialog(deniedList, message, "Allow", "Deny")
            }
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    Timber.d("申请蓝牙定位权限通过")
                    scanBluetoothDevice()
                    //Toast.makeText(this, "所有申请的权限都已通过", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "您拒绝了如下权限：$deniedList", Toast.LENGTH_SHORT).show()
                }
            }
    }

    private fun searchBluetoothDevice() {
        val bluetoothLEAvailable =
            packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
        if (!bluetoothLEAvailable) {
            AppCommonDialog.newInstance("该设备不支持蓝牙功能")
                .show(supportFragmentManager, "AppCommonDialog")
            return
        }
        // 检查权限状态
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val scanPermission: Boolean =
                PermissionX.isGranted(this, Manifest.permission.BLUETOOTH_SCAN)
            val advertisePermission: Boolean =
                PermissionX.isGranted(this, Manifest.permission.BLUETOOTH_ADVERTISE)
            val connectPermission: Boolean =
                PermissionX.isGranted(this, Manifest.permission.BLUETOOTH_CONNECT)
            if (!scanPermission || !advertisePermission || !connectPermission) {
                // 有一个或多个权限未授予，需要申请权限
                Timber.d("申请蓝牙权限")
                requestBluetoothPermission()
            } else {
                // 权限已授予，跳转到蓝牙页面
                scanBluetoothDevice()
            }
        } else {
            // 处理 Android 12 之前的版本
            checkLocationPermissions()
        }
    }

    private fun checkLocationPermissions() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { //28
            val list = arrayListOf<String>()
            // 检查权限状态
            val locationPermission: Boolean = PermissionX.isGranted(
                applicationContext,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
            if (!locationPermission) {
                list.add(Manifest.permission.ACCESS_FINE_LOCATION)
            }
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                val accessPermission: Boolean = PermissionX.isGranted(
                    applicationContext,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                )
                if (!accessPermission) {
                    list.add(Manifest.permission.ACCESS_COARSE_LOCATION)
                }
            }
            if (list.size > 0) {
                // 有一个或多个权限未授予，需要申请权限
                Timber.d("申请蓝牙定位权限")
                requestBluetoothLocationPermission(list)
            } else {
                scanBluetoothDevice()
            }
        } else { //31 需要申请位置权限
            scanBluetoothDevice()
        }

    }

    @SuppressLint("MissingPermission")
    private fun scanBluetoothDevice() {
        val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        val bluetoothAdapter = bluetoothManager.adapter
        //蓝牙是的连接状态
        val isConnected =
            bluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED
        if (null == bluetoothAdapter || !bluetoothAdapter.isEnabled) {
            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            activityLauncher.launch(enableBtIntent)
            return
        }
        //如果此设备不支持被搜索到，则其他设备将无法 发现并连接到它。
        if (!bluetoothAdapter.isMultipleAdvertisementSupported) {
            AppCommonDialog.newInstance("该设备蓝牙功能不可用")
                .show(supportFragmentManager, "AppCommonDialog")
            return
        }
        Timber.d("开始扫描")
        showLoading()
        viewModel.startScan()
    }


    override fun onPause() {
        super.onPause()
        hidLoadingDialog()
        viewModel.stopScanning()
    }

    fun hidLoadingDialog() {
        handler.removeCallbacksAndMessages(null)
        loadingDialog?.dismiss()
        loadingDialog = null
    }

    private fun showLoading() {
        binding.progressBar.startNestedScroll(5)
        binding.progressBar.visibility = View.VISIBLE
    }

    private fun showError(content: String) {
        stopProgressView()
        Toast.makeText(this, content, Toast.LENGTH_SHORT).show()
    }

    private fun showResults(scanDeviceList: ArrayList<WifiDevice>) {
        binding.bluetoothList.models = scanDeviceList
    }

    private fun stopProgressView() {
        binding.tvScanDevice.isEnabled = true
        binding.progressBar.stopNestedScroll()
        binding.progressBar.clearAnimation()
        binding.progressBar.visibility = View.GONE
    }
}